package com.motu.monstercity.server.game.verticle;


import com.motu.data.MotuAdManager;
import com.motu.data.MotuBiManager;
import com.motu.data.UserLoginDevice;
import com.motu.monstercity.module.common.redis.RedisKey;
import com.motu.monstercity.module.common.utility.EventBusConstant;
import com.motu.monstercity.protocol.Common.PBOffEarn;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.CsGameSystem.CSGameSystemPushDataResponse;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.system.SystemConstant;
import com.motu.monstercity.server.game.log.ThinkingDataManager;
import com.motu.monstercity.server.game.logic.*;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.logsdk.AdjustManager;
import com.motu.vertx.module.utility.logsdk.ReyunManager;
import com.motu.vertx.module.utility.logsdk.ToutiaoManager;
import com.motu.vertx.module.utility.redis.RedisTools;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.MessageConsumer;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GameInitVerticle extends AbstractVerticle {
	public static final Logger logger = LoggerFactory.getLogger(GameInitVerticle.class);

	@Override
	public void start(Promise<Void> future) {
		EventBus eb = vertx.eventBus();

		MessageConsumer<JsonObject> consumer = eb.consumer(EventBusConstant.getAddress(EventBusConstant.GAME_INIT));
		consumer.handler(message -> {
			JsonObject obj = message.body();
			long userId = obj.getLong("userId");
			boolean isLoadInitCoord = obj.containsKey("loadInitCoord");// 加载 地图的初始数据
			if (isLoadInitCoord) {
				loadInitCoord(obj, userId);
			} else {
				gameInit(obj, userId);
			}

		});

		consumer.completionHandler(res2 -> {
			if (res2.succeeded()) {
				logger.info("The GameInitVerticle handler registration has reached all nodes");
				future.complete();
			} else {
				logger.error("Registration GameInitVerticle failed! " + res2.cause().toString());
				future.fail(res2.cause());
			}
		});
	}

	// 加载 地图的初始数据, 只生成地铁的初始坐标的用户数据,不需要下发给客户端,客户端自己从build_init_coord加载了
	private void loadInitCoord(JsonObject obj, long userId) {
		try {
			JsonArray jsonArray = obj.getJsonArray("clearList");// 已拆除的列表
			UserCityInfo userCityInfo = BuildManager.getUserCityInfo(userId);
			if (userCityInfo.getIsInitCoord() == 0) {
				BuildManager.loadUserCityCoord(userId, jsonArray);
				userCityInfo.putIsInitCoord(1);// 标识为已加载过了
				userCityInfo.update();
			}
		} catch (Exception e) {
			logger.error("loadInitCoord error: " + e.getCause().getMessage());
		}
	}

	// init,reload 异步执行的逻辑
	private void gameInit(JsonObject obj, long userId) {
		boolean isReload = obj.containsKey("isReload");

		// 避免reload init 同时执行,需要加锁
		long curTime = TimeUtils.getCurTime();
		String lockKey = RedisKey.getUserInitKey(userId);
		boolean init = Future.await(RedisTools.setnx(lockKey, "1"));
		if (init){
			try {
				CSGameSystemPushDataResponse.Builder response = CSGameSystemPushDataResponse.newBuilder();
				PBUserData.Builder pbUserData = response.getUserBuilder();
				UserInfo userInfo = GameUser.getUserInfo(userId);
				UserExtInfo userExtInfo = GameUser.getUserExtInfo(userId);
				long loginTime = userInfo.getLoginTime();
				boolean isFirstLogin = obj.getBoolean("firstLogin", false);// 角色第一次登录
				boolean isFirstLoginToday = obj.getBoolean("firstLoginToday", !TimeUtils.isToday(loginTime));// 今天第一次登录
				String clientVersion = obj.getString("clientVersion");// 客户端版本号
				String packageVersion = obj.getString("packageVersion");// 客户端整包版本号


				if (isFirstLogin) {//  角色第一次登录
					handleFirstLogin(pbUserData, userInfo, userExtInfo);
				}
				UserLoginDevice userLoginDevice = GameUser.getUserLoginDevice(userId);// 用户登录设备信息
				//每次登陆更新ip和客户端版本号
				if (!Tool.isEmpty(userLoginDevice.getIp())) {
					userExtInfo.putIp(userLoginDevice.getIp());
				}
				if (!Tool.isEmpty(clientVersion)) {
					userExtInfo.putClientVersion(clientVersion);
				}
				if (!Tool.isEmpty(packageVersion)) {
					userExtInfo.putPackageVersion(packageVersion);
				}
				//热云-登陆事件
				ReyunManager.sendLoginEvent(userId,userLoginDevice);

				// adjust-登陆事件
				AdjustManager.sendEvent(userId,userLoginDevice,AdjustManager.ROLE_LOGIN,0);

				// 魔兔广告事件-登陆事件
				MotuAdManager.sendLoginEvent(userId, userLoginDevice);

				// 魔兔BI事件-登陆事件
				MotuBiManager.sendLoginEvent(userId, userLoginDevice);

				//数数SDK登录事件
				ThinkingDataManager.pushLoginEvent(userInfo, userLoginDevice, isFirstLogin);
				//数数SDK统计累加登录次数
				ThinkingDataManager.pushUserLoginData(userId);

				if (isFirstLogin) {
					//注册日志
					userExtInfo.putRyDeviceType(userLoginDevice.getDeviceType());
					userExtInfo.putDeviceId(userLoginDevice.getDeviceId());
					userExtInfo.putIdfa(userLoginDevice.getIdfa());
					userExtInfo.putIdfv(userLoginDevice.getIdfv());
					userExtInfo.putImei(userLoginDevice.getImei());
					userExtInfo.putAndroidId(userLoginDevice.getAndroidId());
					userExtInfo.putRyOs(userLoginDevice.getRyos());
					//头条-注册事件
					ToutiaoManager.sendRegisterEvent(userId, userLoginDevice);

					//热云-注册事件
					ReyunManager.sendRegisterEvent(userId,userLoginDevice);

					// adjust-注册事件
					AdjustManager.sendEvent(userId,userLoginDevice,AdjustManager.ROLE_CREATE,0);

					// 魔兔广告事件-注册事件
					MotuAdManager.sendRegisterEvent(userId, userLoginDevice);

					// 魔兔BI事件-注册事件
					MotuBiManager.sendRegisterEvent(userId, userLoginDevice);
				}

				if (isFirstLoginToday) {// 今天第一次登录
					handleFirstLoginToday(pbUserData, userInfo, userExtInfo, userLoginDevice);
				}

				if (isReload) {//0 点重载
					handleReload(pbUserData, userInfo, userExtInfo);
				} else {// 登录时处理的业务逻辑
				}
				UserAffair userAffair = GameUser.getUserAffair(userId);
				UserPower userPower = GameUser.getUserPower(userId);
				long offTime = TimeUtils.getTimeDiff(userAffair.getEarnTime());// 离线时间
				long offGoldNum = BuildManager.countTotalEarnNow(pbUserData, userInfo, userPower, userAffair, true);// 按离线时的收益 结算城市的离线收益 要放在兽潮自动战斗后面,战斗的胜利失败会影响收益
				ProtoDataUtils.updatePBUserData(pbUserData, takeOffEarn(offTime, offGoldNum));// 下发离线时间和离线收益给客户端




				// 限时活动补发奖励
				RankActManager.reissueTask(pbUserData, userInfo);
				RankActManager.updateUserRank(userInfo);

//				UnionScuffleManager.resetUnionScuffleInfo(userId);

				if (isFirstLoginToday) {
					MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_166, 1);// 更新主线任务,成就,日常任务的进度
					RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_166, 1);
				}

				userExtInfo.update();

				MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_1, 1);// 更新主线任务,成就,日常任务的进度
				RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_1, 1);

				//维护补偿活动
				ActManager.checkAllAct(userInfo, userExtInfo);//维护补偿奖励(或其他活动需要处理)

				ProtoDataUtils.updatePBUserData(pbUserData, userInfo);
				ProtoDataUtils.updatePBUserData(pbUserData, userExtInfo);
				GameUser.pushPBUserData(userId, response);//推送PBUserData给客户端进行更新

				// 给客户端推送红点提示
				GameUser.sendRedPointPrompt(userInfo, userExtInfo, SystemConstant.RED_POINT_TYPE_INIT);
			} finally {
				// 释放锁
				boolean delResult = Future.await(RedisTools.del(lockKey));
			}
		} else{
			logger.warn("CMD_GAME_SYSTEM_INIT lock userid:" + userId);
		}
	}

	// 今日第一次登录
	public void handleFirstLoginToday(PBUserData.Builder pbUserData, UserInfo userInfo, UserExtInfo userExtInfo,UserLoginDevice userLoginDevice) {
		FightManager.sendSnatchRankRewardMail(userInfo);// // 给玩家发放物资争夺的榜单奖励邮件
		SecretaryManager.reCountBusiness(userInfo);// 登录时异步重算秘书的经营技能

		// adjust-累计登录几天
		AdjustManager.sendEvent(userInfo.getId(), userLoginDevice, AdjustManager.LOGIN, userExtInfo.getLoginDayCount());

		// 删除在线事件
		EventManager.checkDelOnlineEvent(pbUserData, userInfo);
	}

	// 角色第一次登录
	public void handleFirstLogin(PBUserData.Builder pbUserData, UserInfo userInfo, UserExtInfo userExtInfo) {

	}

	// 0点重载执行的逻辑
	public void handleReload(PBUserData.Builder pbUserData, UserInfo userInfo, UserExtInfo userExtInfo) {
		long userId = userInfo.getId();
		logger.info("handleGameReload userId:" + userId);
		long stime = System.currentTimeMillis();

		// 处理登录逻辑
		UserLoginDevice userLoginDevice = GameUser.getUserLoginDevice(userId);// 用户登录设备信息
		SystemManager.doLogin(pbUserData, userInfo, userExtInfo, userLoginDevice);
		userInfo.updateQueueNow();// 登录时间需要立即更新
		userExtInfo.update();

		// 还有哪些数据0点重载需要更新到客户端的,放在这里


		// 打印reload执行时间
		long initTime = (System.currentTimeMillis() - stime);
		logger.info("######## system.reload time：" + initTime + " userId:" + userId);
	}

	private PBOffEarn.Builder takeOffEarn(long offTime, long offEarn) {
		PBOffEarn.Builder builder = PBOffEarn.newBuilder();
		builder.setOffTime(offTime);
		builder.setOffGoldNum(offEarn);
		return builder;
	}


}
